home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / os2 / ext2_200.zip / EXT2_SRC.ZIP / 32BITS / EXT2-OS2 / FSD32 / FS32_OPE.C < prev    next >
C/C++ Source or Header  |  1996-09-21  |  15KB  |  442 lines

  1. //
  2. // $Header: D:/32bits/ext2-os2/fsd32/RCS/fs32_opencreate.c,v 1.1 1996/09/21 22:25:33 Willm Exp Willm $
  3. //
  4.  
  5. // 32 bits Linux ext2 file system driver for OS/2 WARP - Allows OS/2 to
  6. // access your Linux ext2fs partitions as normal drive letters.
  7. // Copyright (C) 1995, 1996 Matthieu WILLM
  8. //
  9. // This program is free software; you can redistribute it and/or modify
  10. // it under the terms of the GNU General Public License as published by
  11. // the Free Software Foundation; either version 2 of the License, or
  12. // (at your option) any later version.
  13. //
  14. // This program is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. // GNU General Public License for more details.
  18. //
  19. // You should have received a copy of the GNU General Public License
  20. // along with this program; if not, write to the Free Software
  21. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22. #ifdef __IBMC__
  23. #pragma strings(readonly)
  24. #endif
  25.  
  26.  
  27. #define INCL_DOS
  28. #define INCL_DOSERRORS
  29. #define INCL_NOPMAPI
  30. #include <os2.h>
  31.  
  32. #include <string.h>
  33.  
  34. #include <os2/types.h>
  35. #include <os2/StackToFlat.h>
  36. #include <linux/fs.h>
  37. #include <os2/os2proto.h>
  38. #include <os2/fsd32.h>
  39. #include <os2/fsh32.h>
  40. #include <os2/DevHlp32.h>
  41. #include <os2/log.h>
  42. #include <os2/trace.h>
  43. #include <os2/errors.h>
  44. #include <os2/files.h>
  45. #include <os2/volume.h>
  46. #include <linux/fs_proto.h>
  47. #include <linux/stat.h>
  48. #include <os2/vfsapi.h>
  49. #include <os2/ifsdbg.h>
  50. #include <linux/fcntl.h>
  51.  
  52. #define THISFILE FILE_TEST_C    // obsolete
  53. /***********************************************************************************/
  54. /*** Some useful defines for FS_OPENCREATE() ...                                 ***/
  55. /***********************************************************************************/
  56.  
  57.    #define OPEN_ACCESS_MASK               0x0007  /* ---- ---- ---- -111 */
  58.    #define OPEN_ACCESS_EXECUTE            0x0003  /* ---- ---- ---- -100 */
  59.  
  60.    #define OPEN_SHARE_MASK                0x0070  /* ---- ---- -111 ---- */
  61.    #define OPEN_LOCALITY_MASK             0x0700  /* ---- -111 ---- ---- */
  62.    #define OPEN_ACTION_EXIST_MASK         0x000F  /* ---- ---- ---- 1111 */
  63.    #define OPEN_ACTION_NEW_MASK           0x00F0  /* ---- ---- 1111 ---- */
  64.  
  65. #define FILE_NONFAT     0x0040                // File is non 8.3 compliant
  66.  
  67.     extern char write_through_support;
  68.  
  69.  
  70.  
  71.  
  72. /*
  73.  * struct fs32_opencreate_parms {
  74.  *     PTR16          pfgenflag;
  75.  *     PTR16          pEABuf;
  76.  *     unsigned short attr;
  77.  *     PTR16          pAction;
  78.  *     unsigned short openflag;
  79.  *     unsigned long  openmode;
  80.  *     PTR16          psffsd;
  81.  *     PTR16          psffsi;
  82.  *     unsigned short iCurDirEnd;
  83.  *     PTR16          pName;
  84.  *     PTR16          pcdfsd;
  85.  *     PTR16          pcdfsi;
  86.  * };
  87.  */
  88. int FS32ENTRY fs32_opencreate(struct fs32_opencreate_parms *parms) {
  89.     char           *pName;
  90. //    struct cdfsi32 *pcdfsi;
  91. //    union  cdfsd32 *pcdfsd;
  92.     struct sffsi32 *psffsi;
  93.     union  sffsd32 *psffsd;
  94.     unsigned short *pAction;
  95.     int             rc;
  96.     struct super_block * sb;
  97.     struct file   *p_file, *dir;
  98.     UINT32 openmode, DOSmode;
  99.     UINT32 accessmode;
  100.     UINT16 newflag, existflag;
  101.     char component[CCHMAXPATH];
  102.     char parent[CCHMAXPATH];
  103.     struct inode *inode;
  104.     struct inode *inode_parent;
  105.     ino_t         ino_no;
  106.  
  107.     parms = __StackToFlat(parms);
  108.  
  109.     if ((rc = DevHlp32_VirtToLin(parms->psffsi, __StackToFlat(&psffsi))) == NO_ERROR) {
  110.         if ((rc = DevHlp32_VirtToLin(parms->psffsd, __StackToFlat(&psffsd))) == NO_ERROR) {
  111.             if ((rc = DevHlp32_VirtToLin(parms->pName, __StackToFlat(&pName))) == NO_ERROR) {
  112. //                if ((rc = DevHlp32_VirtToLin(parms->pcdfsi, __StackToFlat(&pcdfsi))) == NO_ERROR) {
  113. //                    if ((rc = DevHlp32_VirtToLin(parms->pcdfsd, __StackToFlat(&pcdfsd))) == NO_ERROR) {
  114.                         if ((rc = DevHlp32_VirtToLin(parms->pAction, __StackToFlat(&pAction))) == NO_ERROR) {
  115.  
  116.  
  117.     if (trace_FS_OPENCREATE) {
  118.         kernel_printf("FS_OPENCREATE(%s)", pName);
  119.     }
  120.  
  121.     //
  122.     // Process identification (to recognize DOS box requests)
  123.     //
  124.     DOSmode = (is_case_retensive() ? OPENMODE_DOSBOX : 0);
  125.  
  126.     //
  127.     // Gets the superblock from psffsi
  128.     //
  129.     sb = getvolume(psffsi->sfi_hVPB);
  130.  
  131. #ifdef FS_TRACE
  132.     if (parms->ulOpenMode & OPEN_FLAGS_DASD) {
  133.         fs_log("OPEN_FLAGS_DASD");
  134.     }
  135.  
  136.  
  137.     if (parms->ulOpenMode & OPEN_FLAGS_WRITE_THROUGH) {
  138.         fs_log("OPEN_FLAGS_WRITE_THROUGH");
  139.     }
  140.     if (parms->ulOpenMode & OPEN_FLAGS_FAIL_ON_ERROR) {
  141.         fs_log("OPEN_FLAGS_FAIL_ON_ERROR");
  142.     }
  143.     if (parms->ulOpenMode & OPEN_FLAGS_NO_CACHE) {
  144.         fs_log("OPEN_FLAGS_NO_CACHE");
  145.     }
  146.     if (parms->ulOpenMode & OPEN_FLAGS_NOINHERIT) {
  147.         fs_log("OPEN_FLAGS_NO_INHERIT");
  148.     }
  149. #endif
  150.     accessmode = parms->ulOpenMode & OPEN_ACCESS_MASK;
  151.  
  152.     if (accessmode == OPEN_ACCESS_READONLY) {
  153. #ifdef FS_TRACE
  154.         fs_log("OPEN_ACCESS_READONLY");
  155. #endif
  156.         openmode = OPENMODE_READONLY;
  157.     }
  158.  
  159.     if (accessmode == OPEN_ACCESS_WRITEONLY) {
  160. #ifdef FS_TRACE
  161.         fs_log("OPEN_ACCESS_WRITEONLY");
  162. #endif
  163.         openmode = OPENMODE_WRITEONLY;
  164.     }
  165.  
  166.     if (accessmode == OPEN_ACCESS_READWRITE) {
  167. #ifdef FS_TRACE
  168.         fs_log("OPEN_ACCESS_READWRITE");
  169. #endif
  170.         openmode = OPENMODE_READWRITE;
  171.     }
  172.  
  173. #ifdef FS_TRACE
  174.     if (accessmode == OPEN_ACCESS_EXECUTE) {
  175.         fs_log("OPEN_ACCESS_EXECUTE");
  176.     }
  177. #endif
  178.  
  179.     newflag = parms->openflag & OPEN_ACTION_NEW_MASK;
  180.  
  181. #ifdef FS_TRACE
  182.     if (newflag == OPEN_ACTION_FAIL_IF_NEW) {
  183.         fs_log("OPEN_ACTION_FAIL_IF_NEW");
  184.     }
  185.     if (newflag == OPEN_ACTION_CREATE_IF_NEW) {
  186.         fs_log("OPEN_ACTION_CREATE_IF_NEW");
  187.     }
  188. #endif
  189.  
  190.     existflag = parms->openflag & OPEN_ACTION_EXIST_MASK;
  191.  
  192. #ifdef FS_TRACE
  193.     if (existflag == OPEN_ACTION_OPEN_IF_EXISTS) {
  194.         fs_log("OPEN_ACTION_OPEN_IF_EXISTS");
  195.     }
  196.     if (existflag == OPEN_ACTION_FAIL_IF_EXISTS) {
  197.         fs_log("OPEN_ACTION_FAIL_IF_EXISTS");
  198.     }
  199.     if (existflag == OPEN_ACTION_REPLACE_IF_EXISTS) {
  200.         fs_log("OPEN_ACTION_REPLACE_IF_EXISTS");
  201.     }
  202. #endif
  203.  
  204.     if ((!Read_Write) &&
  205.         ((accessmode == OPEN_ACCESS_READWRITE) ||
  206.          (accessmode == OPEN_ACCESS_WRITEONLY))) {
  207.         fs_log("FS_OPENCREATE() - Write access not enabled");
  208.         return ERROR_WRITE_PROTECT;
  209.     }
  210.  
  211.     //
  212.     // Direct access open of the whole device
  213.     //
  214.     if (parms->ulOpenMode & OPEN_FLAGS_DASD) {
  215.         kernel_printf("OPEN_FLAGS_DASD");
  216.         if ((p_file = _open_by_inode(sb, INODE_DASD, openmode)) == 0) {
  217.             kernel_printf("FS_OPENCREATE() - couldn't DASD open %s", pName);
  218.             return ERROR_OPEN_FAILED;
  219.         }
  220.         psffsd->f = p_file;
  221.         psffsi->sfi_tstamp   = ST_SCREAT | ST_PCREAT;
  222.         psffsi->sfi_size     = p_file->f_inode->i_size;
  223.         psffsi->sfi_position = p_file->f_pos;
  224.         date_unix2dos(p_file->f_inode->i_ctime, &(psffsi->sfi_ctime), &(psffsi->sfi_cdate));
  225.         date_unix2dos(p_file->f_inode->i_atime, &(psffsi->sfi_atime), &(psffsi->sfi_adate));
  226.         date_unix2dos(p_file->f_inode->i_mtime, &(psffsi->sfi_mtime), &(psffsi->sfi_mdate));
  227.         return NO_ERROR;
  228.  
  229.     }
  230.  
  231.     //
  232.     // Now that we treated the OPEN_FLAGS_DASD special case, lets treat the general case :
  233.     // Try to open the file readonly
  234.     // Success : the file exists
  235.     //     if !S_ISDIR && !S_ISREG => error
  236.     //     if OPEN_ACTION_FAIL_IF_EXISTS set => error
  237.     //     if OPEN_ACTION_OPEN_IF_EXISTS set
  238.     //         <test file attrs>
  239.     //         change the open mode and return OK
  240.     //     if OPEN_ACTION_REPLACE_IF_EXISTS set
  241.     //         OPEN_ACCESS_READONLY or OPEN_ACCESS_EXECUTE set => error
  242.     //         OPEN_ACCESS_READWRITE or OPEN_ACCESS_WRITEONLY set
  243.     //             truncate
  244.     //             change openmode and return
  245.     // Failure : the file does not exist
  246.     //     OPEN_ACCESS_READONLY or OPEN_ACCESS_EXECUTE set => error
  247.     //     OPEN_ACCESS_READWRITE or OPEN_ACCESS_WRITEONLY set
  248.     //         if OPEN_ACTION_CREATE_IF_NEW set
  249.     //             try to create the file
  250.     //             open the file and return
  251.     //         if OPEN_ACTION_FAIL_IF_NEW   set => error
  252.  
  253.     p_file = _open_by_name(sb, pName, openmode | DOSmode);
  254.     if (p_file) {        // The file exists
  255.         //
  256.         // If it's not a regular file or a directory we cannot open
  257.         //
  258.         if (!S_ISREG(p_file->f_inode->i_mode)) {
  259.             kernel_printf("Can't FS_OPENCREATE - %s is not a regular file", pName);
  260.             if ((rc = vfs_close(p_file)) != NO_ERROR) {
  261.                 fs_err(FUNC_FS_OPENCREATE, FUNC_CLOSE, rc, FILE_TEST_C, __LINE__);
  262.                 return rc;
  263.             }
  264.             return ERROR_ACCESS_DENIED;
  265.         }
  266.         //
  267.         // if OPEN_ACTION_FAIL_IF_EXISTS set => error
  268.         //
  269.         if (existflag == OPEN_ACTION_FAIL_IF_EXISTS) {
  270. #ifdef FS_TRACE
  271.             fs_log("Can't FS_OPENCREATE() - File exists & OPEN_ACTION_FAIL_IF_EXISTS");
  272. #endif
  273.             if ((rc = vfs_close(p_file)) != NO_ERROR) {
  274.                 fs_err(FUNC_FS_OPENCREATE, FUNC_CLOSE, rc, FILE_TEST_C, __LINE__);
  275.                 return rc;
  276.             }
  277.             return ERROR_FILE_EXISTS;
  278.         }
  279.  
  280.         //
  281.         // if OPEN_ACTION_OPEN_IF_EXISTS : OK
  282.         //
  283.         if (existflag == OPEN_ACTION_OPEN_IF_EXISTS) {
  284.             *pAction        = FILE_EXISTED;
  285.         }
  286.  
  287.         //
  288.         // if OPEN_ACTION_REPLACE_IF_EXISTS : truncate
  289.         //
  290.         if (existflag == OPEN_ACTION_REPLACE_IF_EXISTS) {
  291.             p_file->f_inode->i_size = psffsi->sfi_size;
  292.             p_file->f_inode->i_op->truncate(p_file->f_inode);
  293.             p_file->f_inode->i_dirt = 1;
  294.             p_file->f_flags = O_TRUNC;
  295.            *pAction         = FILE_TRUNCATED;
  296. #if 0
  297.             psffsi->sfi_tstamp   = ST_PWRITE | ST_SWRITE;
  298. #else
  299.             /*
  300.              * Time stamping is done by inode routines - Only propagate value.
  301.              */
  302.             psffsi->sfi_tstamp   = ST_PWRITE;
  303. #endif
  304.  
  305.         }
  306.     } else {                // The file doesn't exist
  307.         ExtractPath(pName, __StackToFlat(parent));
  308.         ExtractName(pName, __StackToFlat(component));
  309.         //
  310.         // We try to open the parent dir
  311.         //
  312.         if ((dir = _open_by_name(sb, __StackToFlat(parent), OPENMODE_READONLY | DOSmode)) == 0) {
  313. //            kernel_printf("FS_OPENCREATE() - The parent directory %s doesn't seem to exist", parent);
  314.             return ERROR_PATH_NOT_FOUND;
  315.         }
  316.  
  317.         //
  318.         // The parent dir exists
  319.         //
  320.  
  321.         //
  322.         // If the file is open for execution : error (it doesn't even exist)
  323.         //
  324.         if (accessmode == OPEN_ACCESS_EXECUTE) {
  325. #ifdef FS_TRACE
  326.             fs_log("Can't FS_OPENCREATE() - File doesn't exist & OPEN_ACCESS_EXECUTE");
  327. #endif
  328.             if ((rc = vfs_close(dir)) != NO_ERROR) {
  329.                 fs_err(FUNC_FS_OPENCREATE, FUNC_CLOSE, rc, FILE_TEST_C, __LINE__);
  330.                 return rc;
  331.             }
  332.             return ERROR_FILE_NOT_FOUND;
  333.         }
  334.  
  335.         //
  336.         // If the file is open for writing or readwrite ...
  337.         //
  338.         if ((accessmode == OPEN_ACCESS_READONLY)  ||
  339.             (accessmode == OPEN_ACCESS_READWRITE) ||
  340.             (accessmode == OPEN_ACCESS_WRITEONLY)) {
  341.             if (newflag == OPEN_ACTION_FAIL_IF_NEW) {
  342. #ifdef FS_TRACE
  343.                 fs_log("Can't FS_OPENCREATE() - File doesn't exist &  OPEN_ACTION_FAIL_IF_NEW");
  344. #endif
  345.                 if ((rc = vfs_close(dir)) != NO_ERROR) {
  346.                     fs_err(FUNC_FS_OPENCREATE, FUNC_CLOSE, rc, FILE_TEST_C, __LINE__);
  347.                     return rc;
  348.                 }
  349.                 return ERROR_OPEN_FAILED;
  350.             }
  351.  
  352.             if (newflag == OPEN_ACTION_CREATE_IF_NEW) {
  353. //                ino_no = dir->f_inode->i_ino;
  354.                 inode_parent = dir->f_inode;
  355.                 inode_parent->i_count ++;
  356.                 if ((rc = vfs_close(dir)) != NO_ERROR) {
  357.                     fs_err(FUNC_FS_OPENCREATE, FUNC_CLOSE, rc, THISFILE, __LINE__);
  358.                     return rc;
  359.                 }
  360. //                inode_parent = iget(sb, ino_no);
  361.                 inode_parent->i_count++;
  362.                 down(&inode_parent->i_sem);
  363.                 rc = inode_parent->i_op->create (inode_parent,__StackToFlat(component), strlen(component), S_IRWXU | S_IFREG , __StackToFlat(&inode));
  364.                 up(&inode_parent->i_sem);
  365.                 if (rc) {
  366.                     kernel_printf("Couldn't create %s", pName);
  367.                     iput(inode_parent);
  368.                     return rc;
  369.                 }
  370.                 ino_no = inode->i_ino;
  371.                 iput(inode_parent);
  372.                 iput(inode);
  373.                 if ((p_file = _open_by_inode(sb, ino_no, openmode)) == 0) {
  374.                     kernel_printf("open_by_inode(%lu) failed in FS_OPENCREATE", ino_no);
  375.                     return ERROR_OPEN_FAILED;
  376.                 }
  377.                 p_file->f_inode->i_size = psffsi->sfi_size;
  378.                 p_file->f_inode->i_dirt = 1;
  379.                 p_file->f_flags = O_CREAT;
  380.                 *pAction        = FILE_CREATED;
  381. #if 0
  382.                 psffsi->sfi_tstamp   = ST_SCREAT | ST_PCREAT | ST_PWRITE | ST_SWRITE;
  383. #else
  384.                 /*
  385.                  * Time stamping is done by inode routines - Only propagate value.
  386.                  */
  387.                 psffsi->sfi_tstamp   = ST_PCREAT | ST_PWRITE;
  388. #endif
  389.  
  390.             }
  391.  
  392.         }
  393.  
  394.     }
  395.  
  396.  
  397.  
  398.  
  399.  
  400.    psffsd->f = p_file;
  401.     /*
  402.      * Time stamping is done by inode routines - Only propagate value.
  403.      */
  404. #if 0
  405.     psffsi->sfi_tstamp   |= ST_PREAD | ST_SREAD;
  406. #else
  407.     /*
  408.      * Time stamping is done by inode routines - Only propagate value.
  409.      */
  410.     psffsi->sfi_tstamp   |= ST_PREAD;
  411. #endif
  412.     psffsi->sfi_size      = p_file->f_inode->i_size;
  413.     psffsi->sfi_position  = p_file->f_pos;
  414.  
  415. //    kernel_printf("date = %u/%u/%u", (pCommon->dateCreate) & 31, (pCommon->dateCreate >> 5) & 15 , (pCommon->dateCreate) >> 9);
  416.  
  417.     date_unix2dos(p_file->f_inode->i_ctime, &(psffsi->sfi_ctime), &(psffsi->sfi_cdate));
  418.     date_unix2dos(p_file->f_inode->i_atime, &(psffsi->sfi_atime), &(psffsi->sfi_adate));
  419.     date_unix2dos(p_file->f_inode->i_mtime, &(psffsi->sfi_mtime), &(psffsi->sfi_mdate));
  420.  
  421.     psffsi->sfi_DOSattr =  (unsigned char)Linux_To_DOS_Attrs(p_file->f_inode, __StackToFlat(component));
  422.     if (write_through_support) {
  423.         if ((parms->ulOpenMode & OPEN_FLAGS_WRITE_THROUGH) ||
  424.             (parms->ulOpenMode & OPEN_FLAGS_NO_CACHE)) {
  425.             p_file->f_flags          |= O_SYNC;
  426.             p_file->f_inode->i_flags |= MS_SYNCHRONOUS;
  427.        }
  428.     }
  429.     return NO_ERROR;
  430.  
  431.  
  432.  
  433.  
  434.                         }
  435. //                    }
  436. //                }
  437.             }
  438.         }
  439.     }
  440.     return rc;
  441. }
  442.